﻿#ifndef __ZUICONTROL_H__
#define __ZUICONTROL_H__

#include "ZString.h"
#include "ZUtils.h"
#include "ZScheduler.h"
#include "ZRenderer.h"
#include "ZAttrMap.h"
#include "common/ZDpi.h"
#include "script/ZLuaWindow.h"
#include "ZMacro.h"

namespace ZuiLib
{
class ZWindow;
class ZPaintManager;
class ZRenderer;
class ZControl;
struct ZTextInfo;

struct TEventUI
{
	int Type;
	ZControl* pSender;
	uint32_t dwTimestamp;
	POINT ptMouse;
	SDL_Keycode chKey;
	uint16_t wKeyState;//SDL_Keymod
	uint64_t wParam;
	uint64_t lParam;
};

typedef ZControl* (* FINDCONTROLPROC)(ZControl*, void*);

//按键状态
enum KeyState{
	KS_CTRL=KMOD_CTRL,
	KS_ALT=KMOD_ALT,
	KS_SHIFT=KMOD_SHIFT,
	KS_GUI=KMOD_GUI
};

#define ZCONTROL_CLASS_DEFINE(className,parentClass) \
virtual const char* GetClass() const { \
		return className; \
} \
virtual void* GetInterface(const char* pstrName){ \
    if( strcmp(pstrName, className) == 0 ) \
		return this; \
	else \
		return parentClass::GetInterface(pstrName); \
}



class ZControl:public ZSchedulerBase
{
public:
	ZUI_CLASS_NAME("zui.Control");

	ZControl();
	virtual ~ZControl();
public:
	virtual const char* GetClass() const;
	virtual void* GetInterface(const char* pstrName);

	virtual const ZString& GetName() const;
	virtual void SetName(const char* pstrName);
	virtual uint32_t GetControlFlags() const;

	virtual bool Activate();
	ZPaintManager* GetManager() const;
	virtual void SetManager(ZPaintManager* pManager, ZControl* pParent, bool bInit = true);
	ZRenderer* GetRenerder() const;

	virtual ZControl* GetParent() const;

	// 文本相关
	virtual ZString GetText() const;
	virtual void SetText(const char* pstrText);

	void SetTransText(const char* pstrText);

	// 图形相关
	uint32_t GetBkColor() const;
	void SetBkColor(uint32_t dwBackColor);

	const char* GetBkImage();
	void SetBkImage(const char* pStrImage);
	uint32_t GetFocusBorderColor() const;
	void SetFocusBorderColor(uint32_t dwBorderColor);
	
	//边框相关
	int GetBorderSize() const;
	void SetBorderSize(int nZSize);
	uint32_t GetBorderColor() const;
	void SetBorderColor(uint32_t dwBorderColor);

	bool IsDelayDestroy(){return m_bDelayDestroy;}

	//检查按键状态
	static bool CheckKeyState(KeyState state);


	// 位置相关
	virtual const RECT& GetPos() const;
	virtual void SetPos(RECT rc);
	virtual int GetWidth() const;
	virtual int GetHeight() const;
	virtual int GetX() const;
	virtual int GetY() const;
	virtual RECT GetPadding() const;
	virtual void SetPadding(RECT rcPadding); // 设置外边距，由上层窗口绘制
	virtual SIZE GetFixedXY() const;         // 实际大小位置使用GetPos获取，这里得到的是预设的参考值
	virtual void SetFixedXY(SIZE szXY);      // 仅float为true时有效
	virtual int GetFixedWidth() const;       // 实际大小位置使用GetPos获取，这里得到的是预设的参考值
	virtual void SetFixedWidth(int cx);      // 预设的参考值
	virtual int GetFixedHeight() const;      // 实际大小位置使用GetPos获取，这里得到的是预设的参考值
	virtual void SetFixedHeight(int cy);     // 预设的参考值

	//flex布局参数
	int GetFlexWeight() const;
	void SetFlexWeight(int flexWeight);

	virtual int GetMinWidth() const;
	virtual void SetMinWidth(int cx);
	virtual int GetMaxWidth() const;
	virtual void SetMaxWidth(int cx);
	virtual int GetMinHeight() const;
	virtual void SetMinHeight(int cy);
	virtual int GetMaxHeight() const;
	virtual void SetMaxHeight(int cy);


	// 鼠标提示
	virtual ZString GetToolTip() const;
	virtual void SetToolTip(const char* pstrText);

	void SetTransToolTip(const char* pstrText);

	// 快捷键
	virtual char GetShortcut() const;
	virtual void SetShortcut(char ch);

	// 菜单
	virtual bool IsContextMenuUsed() const;
	virtual void SetContextMenuUsed(bool bMenuUsed);

	// 用户属性
	virtual const ZString& GetUserData(); // 辅助函数，供用户使用
	virtual void SetUserData(const char* pstrText); // 辅助函数，供用户使用
	virtual int64_t GetTag() const; // 辅助函数，供用户使用
	virtual void SetTag(int64_t pTag); // 辅助函数，供用户使用

	// 一些重要的属性
	virtual bool IsVisible() const;
	virtual void SetVisible(bool bVisible = true);

	// 仅供内部调用，有些UI拥有窗口句柄，需要重写此函数
	virtual void SetInternVisible(bool bVisible = true); 
	virtual bool IsEnabled() const;
	virtual void SetEnabled(bool bEnable = true);
	virtual bool IsMouseEnabled() const;
	virtual void SetMouseEnabled(bool bEnable = true);
	virtual bool IsKeyboardEnabled() const;
	virtual void SetKeyboardEnabled(bool bEnable = true);
	virtual bool IsFocused() const;
	virtual void SetFocus();
	virtual bool IsFloat() const;
	virtual void SetFloat(bool bFloat = true);
	
	virtual ZControl* FindControl(FINDCONTROLPROC Proc, void* pData, uint32_t uFlags);

	void Invalidate(const RECT* rcInv=NULL);
	bool IsUpdateNeeded() const;
	void NeedUpdate();
	void NeedParentUpdate();

	virtual void DoInit();
	virtual void DoDeinit();
	inline bool IsInited() { return m_inited; }

	virtual void DoEvent(TEventUI& event);

	virtual void SetAttribute(const char* pstrName, const char* pstrValue);
	void ApplyAttributeList(const char* pstrList);

	//注意szAvailable为真实尺寸
	virtual SIZE EstimateSize(SIZE szAvailable);

	virtual void DoPaint(ZRenderer* render, const RECT& rcPaint);
	virtual void DoPostPaint(ZRenderer* render, const RECT& rcPaint);

	virtual void PaintBkColor(ZRenderer* render);
	virtual void PaintBkImage(ZRenderer* render);
	virtual void PaintStatusImage(ZRenderer* render);
	virtual void PaintText(ZRenderer* render);
	virtual void PaintBorder(ZRenderer* render);

	bool DrawImage(ZRenderer* render, ZImageDrawInfo* drawInfo);
	bool DrawColor(ZRenderer* render,color_t color);

	void AsynSchedule(SEL_SCHEDULE_VOID pfnSelector);//线程安全的
	void ScheduleOnce(SEL_SCHEDULE pfnSelector,Uint32 delay);
	void Schedule(SEL_SCHEDULE pfnSelector,Uint32 delay,Uint32 interval=0,Uint32 repeat=kForever);
	void Unschedule(SEL_SCHEDULE pfnSelector);

	ZTexturePtr Capture();

	uint8_t GetAlpha();
	void SetAlpha(uint8_t alpha);

	ZWindow* GetWindow();

	void ApplyCss(ZPaintManager* manager,const char* elemName, const char* className, const char* name);

	//保存事件属性等
	inline void SetEventAttr(const char* key,const char* value) 
	{
		m_eventAttrMap.Set(key,value);
	}

	inline const char* GetEventAttr(const char* key)
	{
		return m_eventAttrMap.Get(key);
	}

protected:
	DISALLOW_COPY_AND_ASSIGN(ZControl);

	ZPaintManager* m_pManager;
	ZControl* m_pParent;
	ZString m_sName;
	ZAttrMap m_eventAttrMap;
	bool m_bUpdateNeeded;
	bool m_bMenuUsed;
	RECT m_rcItem;//以实际像素为单位,其余的都是以要求的像素为单位
	RECT m_rcPadding;
	SIZE m_cXY;
	SIZE m_cxyFixed;
	SIZE m_cxyMin;
	SIZE m_cxyMax;
	int  m_nFlexWeight;

	bool m_bVisible;
	bool m_bInternVisible;
	bool m_bEnabled;
	bool m_bMouseEnabled;
	bool m_bKeyboardEnabled ;
	bool m_bFocused;
	bool m_bFloat;
	bool m_bDelayDestroy;

	ZString m_sText;
	ZString m_sToolTip;
	char m_chShortcut;
	ZString m_sUserData;
	int64_t m_pTag;

	uint32_t m_dwBackColor;

	ZImageDrawInfo m_sBkImage;
	ZImageDrawInfo m_sForeImage;
	uint32_t m_dwBorderColor;
	uint32_t m_dwFocusBorderColor;

	uint8_t m_alpha;//该控件的alpha值
	int m_nBorderSize;
	int m_nBorderRound;
	RECT m_rcPaint;

	bool m_inited;
};


typedef ZRefCountedPtr<ZControl> ZControlPtr;


template<class T>
ZRefCountedPtr<T> CreateControl() {
	return new ZRefCountedObject<T>();
}

}//namespace

#endif //__ZUICONTROL_H__
